/*
 * Copyright 2007 - The JDPF Project Team (http://www.jdpf.org) 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */
package org.jdpf.plugins.rgbimage.filter.rgbimage.tograyscalefilter;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.jdpf.core.kernel.elements.Token;
import org.jdpf.core.plugins.blocks.AbstractFilterPlugin;
import org.jdpf.core.plugins.datatypes.AbstractDataType;
import org.jdpf.plugins.datatypes.media.RGBImage;

/**
 * @author Bruno Farina
 *
 */
public class ToGrayScaleFilter extends AbstractFilterPlugin {
	
	private static final float RED_LIGHT=0.299f;
	private static final float GREEN_LIGHT=0.587f;
	private static final float BLUE_LIGHT=0.114f;
	
	private String _conversionMode="average";
	
	private double relativePerc;

	public ToGrayScaleFilter(String transitionId, String transitionName) {
		super(transitionId, transitionName);
	}

	@Override
	public Token process(List<Token> list) {
		List<AbstractDataType> outList=new ArrayList<AbstractDataType>(5);
		List<AbstractDataType> inList=list.get(0).getValueList();
		Iterator<AbstractDataType> iter=inList.iterator();
		double tot=0.0;
		List<RGBImage> imageList=new ArrayList<RGBImage>(5);
		int i=0;
		while(iter.hasNext()){
			RGBImage image=(RGBImage) iter.next();
			imageList.add(i,image);
			int[] img=(int[]) image.getValue();
			tot+=img.length;
		}
		for(int j=0;j<imageList.size()&&start;j++){
			RGBImage image=imageList.get(j);
			int[] img=(int[]) image.getValue();
			if(_conversionMode.equals("average")){
				this.log("[INFO] Converting RGB image to an average grayscale.");
				average(img);
			}else if(_conversionMode.equals("weighted")){
				this.log("[INFO] Converting RGB image to a weighted grayscale.");
				weighted(img);
			}
			RGBImage outImage=new RGBImage(img, image.getW(), image.getH(),image.getFileName());
			outList.add(i,outImage);
			percentage=Math.min(100.0,percentage+((relativePerc*img.length)+1)/tot*100);
			i++;
		}
		Token out=new Token();
		out.setValueList(outList);
		return out;
	}

	private void average(int[] img) {
		relativePerc=0.0;
		double tot=img.length+0.0;
		for(int j=0; j<img.length&&start; j++){
			int r = ((img[j] >> 16) & 255);
			int g = ((img[j] >> 8) & 255);
			int b = (img[j] & 255);
			int media = (r + g + b)/3;
			img[j] = ((media << 16) + (media <<8) + media) | 0xff000000;
			relativePerc=Math.min(100.0,(j+1)/tot);
		}
	}

	private void weighted(int[] img) {
		relativePerc=0.0;
		double tot=img.length+0.0;
		for(int j=0; j<img.length&&start; j++){
			int r = ((img[j] >> 16) & 255);
			int g = ((img[j] >> 8) & 255);
			int b = (img[j] & 255);
			int media = (int)((RED_LIGHT*r) + (GREEN_LIGHT*g) + (BLUE_LIGHT*b));
			img[j] = ((media << 16) + (media <<8) + media) | 0xff000000;
			relativePerc=Math.min(100.0,(j+1)/tot);
		}
	}

	public void resetProcessStatus() {
		super.resetProcessStatus();
		relativePerc=0.0;
	}
	
	public void setConversionMode(String conversionMode) {
		this._conversionMode = conversionMode;
	}

}
